package com.lizemin.power.config;

import com.lizemin.power.threadPool.PowerThreadPoolExecutor;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author lzm
 * @date 2025/6/5 19:40
 * @description 线程池配置类
 */
@Configuration
public class ThreadPoolConfig {

    /**
     * 单例JDK线程池对象
     *
     * @return 线程池对象
     */
    @Bean("orderThreadPoolExecutor")
    public ThreadPoolExecutor orderThreadPoolExecutor() {
        final AtomicInteger counter = new AtomicInteger(1);
        ThreadPoolProperties threadPoolProperties = orderThreadPoolProperties();
        return new ThreadPoolExecutor(threadPoolProperties.getCorePoolSize(),
                threadPoolProperties.getMaximumPoolSize(),
                threadPoolProperties.getKeepAliveSeconds(),
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(threadPoolProperties.getQueueCapacity()),
                r -> new Thread(r, threadPoolProperties.getThreadNamePrefix() + "-" + counter.getAndIncrement()),
                new ThreadPoolExecutor.AbortPolicy()
        );
    }

    /**
     * 将手写线程池实例注册到Spring容器中
     *
     * @return 手写线程池对象
     */
    @Bean("powerThreadPoolExecutor")
    public PowerThreadPoolExecutor powerThreadPoolExecutor() {
        final AtomicInteger counter = new AtomicInteger(1);
        ThreadPoolProperties threadPoolProperties = powerThreadPoolProperties();
        return new PowerThreadPoolExecutor(
                threadPoolProperties.getCorePoolSize(),
                threadPoolProperties.getMaximumPoolSize(),
                threadPoolProperties.getQueueCapacity(),
                Long.valueOf(threadPoolProperties.getKeepAliveSeconds()).intValue(),
                TimeUnit.SECONDS,
                r -> new Thread(r, threadPoolProperties.getThreadNamePrefix() + "-" + counter.getAndIncrement())
        );
    }

    @ConfigurationProperties(prefix = "thread-pool.power")
    @Bean
    ThreadPoolProperties powerThreadPoolProperties() {
        return new ThreadPoolProperties();
    }

    @ConfigurationProperties(prefix = "thread-pool.order")
    @Bean
    ThreadPoolProperties orderThreadPoolProperties() {
        return new ThreadPoolProperties();
    }

    @Data
    static class ThreadPoolProperties {
        /**
         * 核心线程数
         */
        private int corePoolSize;

        /**
         * 最大线程数
         */
        private int maximumPoolSize;

        /**
         * 线程空闲时间
         */
        private long keepAliveSeconds;

        /**
         * 队列容量
         */
        private int queueCapacity;

        /**
         * 线程名称前缀
         */
        private String threadNamePrefix;
    }

}
